﻿using Autofac;
using KWT.DRG_DIP.API.Infrastructure;
using KWT.DRG_DIP.DB;
using KWT.DRG_DIP.DO.System;
using KWT.DRG_DIP.DTO.Settlement.List;
using KWT.DRG_DIP.DTO.Statistic;
using KWT.DRG_DIP.DTO.Statistic.Overview;
using KWT.DRG_DIP.ISvc;
using KWT.DRG_DIP.PO.Basic;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace KWT.DRG_DIP.API.Controllers.Statistic
{
    /// <summary>
    /// 综合运营分析
    /// </summary>
    [ApiExplorerSettings(GroupName = "statistic")]
    public class OverviewController : StatisticControllerBase
    {
        public DapperHelper dapper { get; set; }
        private readonly IComponentContext componentContext;
        public OverviewController(IComponentContext _componentContext)
        {
            componentContext = _componentContext;
        }
        /// <summary>
        /// 付费病例
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<OutPart1>), 200)]
        public OutputResult Part1(DTO.Statistic.Overview.InOverview dto)
        {
            var statisticSvc = componentContext.ResolveNamed<IStatisticSvc>(CurrentUser.UsePolicy);
            var result = statisticSvc.Cacl(dto);
            return Output(true, "", "", result);
        }

        /// <summary>
        /// 医疗费用分析
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<OutPart2>), 200)]
        public OutputResult Part2(DTO.Statistic.Overview.InOverview dto)
        {
            var dt1 = Convert.ToDateTime(dto.StartDate);
            var dt2 = Convert.ToDateTime(dto.EndDate);
            string dt = dt1.Year == dt2.Year && dt1.Month == dt2.Month ? "%m-%d" : "%Y-%m";
            string sql1 = @"select sum(Total) total,sum(Remain) remain,DATE_FORMAT(SettleDate, @dt) fmt_date from sys_list a
left join list_chargeinfo b on a.ListID=b.ListID
where SettleDate>=@StartDate and SettleDate<=@EndDate
group by fmt_date
order by fmt_date";
            var list1 = dapper.Select<dynamic>(sql1, new { dto.StartDate, dto.EndDate, dt });
            var series1 = new List<Series>
            {
                new() { name = "总收入", datas = [.. list1.Select(x => x.total).Cast<decimal>()], type = "line", stack = "Total" },
                new() { name = "支付差", datas = [.. list1.Select(x => x.remain).Cast<decimal>()], type = "line", stack = "Total" },
            };


            var line1 = new ECharts_Line()
            {
                legend = ["总收入", "支付差"],
                xAxis = [.. list1.Select(x => x.fmt_date).Cast<string>().Distinct()],
                Series = series1,
            };

            string sql2 = @"select round(sum(remain/10000),2) remain,fmt_date,type from
(select sum(Total) total,sum(Remain) remain,DATE_FORMAT(SettleDate,  @dt) fmt_date,InsureType,'职工' type from sys_list a
left join list_chargeinfo b on a.ListID=b.ListID
left join list_basicinfo c on a.ListID=c.ListID
where SettleDate>=@StartDate and SettleDate<=@EndDate and InsureType=1
group by fmt_date,InsureType
union all
select sum(Total) total,sum(Remain) remain,DATE_FORMAT(SettleDate,  @dt) fmt_date,InsureType,'居民' type from sys_list a
left join list_chargeinfo b on a.ListID=b.ListID
left join list_basicinfo c on a.ListID=c.ListID
where SettleDate>=@StartDate and SettleDate<=@EndDate and InsureType=2
group by fmt_date,InsureType
union all
select sum(Total) total,sum(Remain) remain,DATE_FORMAT(SettleDate,  @dt) fmt_date,InsureType,'其他' type from sys_list a
left join list_chargeinfo b on a.ListID=b.ListID
left join list_basicinfo c on a.ListID=c.ListID
where SettleDate>=@StartDate and SettleDate<=@EndDate and InsureType in(3,4,5,6,7,90,99)
group by fmt_date,InsureType) a
group by fmt_date,type
order by fmt_date";

            var list2 = dapper.Select<dynamic>(sql2, new { dto.StartDate, dto.EndDate, dt });
            var series2 = new List<Series>
            {
                new() { name = "职工", datas = [.. list2.Where(x=>x.type== "职工").Select(x => x.remain).Cast<decimal>()], type = "line", stack = "Total" },
                new() { name = "居民", datas = [.. list2.Where(x => x.type == "居民").Select(x => x.remain).Cast<decimal>()], type = "line", stack = "Total" },
                 new() { name = "其他", datas = [.. list2.Where(x => x.type == "其他").Select(x => x.remain).Cast<decimal>()], type = "line", stack = "Total" },
            };


            var line2 = new ECharts_Line()
            {
                legend = ["职工", "居民", "其他"],
                xAxis = [.. list2.Select(x => x.fmt_date).Cast<string>().Distinct()],
                Series = series2,
            };

            string sql3 = @"select sum(amount) value ,ItemName name from sys_list a
left join chargeinfo_item b on a.ListID=b.ListID
where SettleDate>=@StartDate and SettleDate<=@EndDate
GROUP BY ItemName";
            var list3 = dapper.Select<PieData>(sql3, new { dto.StartDate, dto.EndDate });

            string sql4 = @"select sum(Total) Total,sum(Remain) Remain,b.`Name` CategoryName from sys_list a
left join sys_category b on a.CategoryID=b.CategoryID
left join list_chargeinfo c on a.ListID=c.ListID
where SettleDate>=@StartDate and SettleDate<=@EndDate
GROUP BY b.`Name`
order by total desc
limit 10";
            var list4 = dapper.Select<BarData>(sql4, new { dto.StartDate, dto.EndDate });

            var result = new OutPart2()
            {
                Bar = list4.ToList(),
                Line1 = line1,
                Line2 = line2,
                Pie = list3.ToList()
            };
            return Output(true, "", "", result);
        }

        /// <summary>
        /// 医疗服务能力评价
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<OutPart3>), 200)]
        public OutputResult Part3(DTO.Statistic.Overview.InOverview dto)
        {
            var statisticSvc = componentContext.ResolveNamed<IStatisticSvc>(CurrentUser.UsePolicy);
            var result = statisticSvc.Part3(dto);
            return Output(true, "", "", result);
        }

        /// <summary>
        /// 服务效率评价
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<OutPart4>), 200)]
        public OutputResult Part4(DTO.Statistic.Overview.InOverview dto)
        {
            var statisticSvc = componentContext.ResolveNamed<IStatisticSvc>(CurrentUser.UsePolicy);
            var result = statisticSvc.Part4(dto);
            return Output(true, "", "", result);
        }

        /// <summary>
        /// 医疗安全相关评价
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<OutPart5>), 200)]
        public OutputResult Part5(DTO.Statistic.Overview.InOverview dto)
        {
            var dt1 = Convert.ToDateTime(dto.StartDate);
            var dt2 = Convert.ToDateTime(dto.EndDate);
            string dt = dt1.Year == dt2.Year && dt1.Month == dt2.Month ? "%m-%d" : "%Y-%m";
            var paras = new { dto.StartDate, dto.EndDate, dt };
            string sql1 = @" select count(1) value,DATE_FORMAT(SettleDate, @dt) fmt_date,'死亡病例数' type from sys_list a
inner join list_diaginfo c on a.ListID=c.ListID
 where  SettleDate>=@StartDate and SettleDate<=@EndDate and outway=5
group by fmt_date
order by fmt_date";
            var list1 = dapper.Select<BarLine>(sql1, paras);

            string sql2 = @" select count(1) value,DATE_FORMAT(SettleDate,  @dt) fmt_date,'出院病例数' type from sys_list a
inner join list_diaginfo c on a.ListID=c.ListID
where SettleDate>=@StartDate and SettleDate<=@EndDate 
group by fmt_date
order by fmt_date";
            var list2 = dapper.Select<BarLine>(sql2, paras);

            var _list3 = new List<BarLine>();
            foreach (var item in list2)
            {
                var _item = list1.SingleOrDefault(x => x.fmt_date == item.fmt_date);
                if (_item != null)
                {
                    _list3.Add(new BarLine() { fmt_date = item.fmt_date, type = "死亡率", value = item.value / _item.value * 100 });
                }
                else
                {
                    _list3.Add(new BarLine() { fmt_date = item.fmt_date, type = "死亡率", value = 0 });
                }
            }

            string sql3 = @" select count(1) value,DATE_FORMAT(SettleDate,  @dt) fmt_date,'低风险死亡病例数' type from sys_list a
inner join list_diaginfo b on a.ListID=b.ListID
 where left(Diag_Code,3) in (select value from sys_enum where `Group`='低风险病种') and SettleDate>=@StartDate and SettleDate<=@EndDate and outway=5
 group by fmt_date order by fmt_date";
            var list3 = dapper.Select<BarLine>(sql3, paras);

            string sql4 = @" select count(1) value,DATE_FORMAT(SettleDate,  @dt) fmt_date,'低风险病种病例数' type from sys_list a
 where left(Diag_Code,3) in (select value from sys_enum where `Group`='低风险病种') and SettleDate>=@StartDate and SettleDate<=@EndDate
 group by fmt_date order by fmt_date";
            var list4 = dapper.Select<BarLine>(sql4, paras);

            var _list4 = new List<BarLine>();
            foreach (var item in list4)
            {
                var _item = list3.SingleOrDefault(x => x.fmt_date == item.fmt_date);
                if (_item != null)
                {
                    _list4.Add(new BarLine() { fmt_date = item.fmt_date, type = "低风险死亡率", value = item.value / _item.value * 100 });
                }
                else
                {
                    _list4.Add(new BarLine() { fmt_date = item.fmt_date, type = "低风险死亡率", value = 0 });
                }
            }

            string sql5 = @" select count(1) value,DATE_FORMAT(SettleDate, @dt) fmt_date,'高倍率病例数' type from sys_list a
 where MagType=1 and SettleDate>=@StartDate and SettleDate<=@EndDate
 group by fmt_date order by fmt_date";
            var list5 = dapper.Select<BarLine>(sql5, paras);

            string sql6 = @" select count(1) value,DATE_FORMAT(SettleDate, @dt) fmt_date,'低倍率病例数' type from sys_list a
 where MagType=2 and SettleDate>=@StartDate and SettleDate<=@EndDate
 group by fmt_date order by fmt_date";
            var list6 = dapper.Select<BarLine>(sql6, paras);

            var _list6 = new List<BarLine>();
            foreach (var item in list2)
            {
                var _item = list5.SingleOrDefault(x => x.fmt_date == item.fmt_date);
                if (_item != null)
                {
                    _list6.Add(new BarLine() { fmt_date = item.fmt_date, type = "高倍率占比", value = item.value / _item.value * 100 });
                }
                else
                {
                    _list6.Add(new BarLine() { fmt_date = item.fmt_date, type = "高倍率占比", value = 0 });
                }
            }

            var _list7 = new List<BarLine>();
            foreach (var item in list2)
            {
                var _item = list6.SingleOrDefault(x => x.fmt_date == item.fmt_date);
                if (_item != null)
                {
                    _list7.Add(new BarLine() { fmt_date = item.fmt_date, type = "低倍率占比", value = item.value / _item.value * 100 });
                }
                else
                {
                    _list7.Add(new BarLine() { fmt_date = item.fmt_date, type = "低倍率占比", value = 0 });
                }
            }
            var result = new OutPart5()
            {
                BarLine1 = list1.Concat(_list3).Concat(list3).Concat(list4).Concat(_list4).ToList(),
                BarLine2 = list5.Concat(list6).Concat(_list6).Concat(_list7).ToList(),
            };
            return Output(true, "", "", result);
        }
    }
}
